package service

import (
	"duoke/context"
	"duoke/internal/dao"
	"duoke/model"
	utils "duoke/utils/common"
	"duoke/utils/gconv"
	"duoke/utils/gjson"
	"duoke/utils/orm"
	"duoke/utils/redislib"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gogf/gf/v2/container/gvar"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/sirupsen/logrus"
)

var FastMail = new(fastMailService)

type fastMailService struct{}

func (s *fastMailService) Query(c *gin.Context, req *model.SearchFastMail) (*model.ReqFastMail, error) {
	var rsp model.ReqFastMail
	err := dao.Fastmail.Ctx(c).Where("nu=?", req.Num).Scan(&rsp)
	if err == nil || (rsp.Data != nil && rsp.State == "3") {
		rsp.Data = gvar.New(rsp.Data, true).Array()
		return &rsp, nil
	}
	flag := utils.FastMail().GetKd100Flags(req.Com)
	if flag == "" {
		return nil, errors.New("暂不支持此快递公司")
	}
	redisKey := "kuaidi100:" + req.Num
	if redislib.Redis.Get(c, redisKey).Val() != "" {
		val := redislib.Redis.Get(c, redisKey).Val()
		gjson.Json2StructOrMap(val, &rsp)
		return &rsp, nil
	}

	m := map[string]any{
		"com":   flag,
		"num":   req.Num,
		"phone": req.Phone,
	}
	query, err := utils.FastMail().Query(c, m, "https://poll.kuaidi100.com/poll/query.do")
	logrus.Info("快递10：", query)
	if err != nil {
		return nil, err
	}
	gjson.Json2StructOrMap(query, &rsp)
	if rsp.Status != "200" {
		return nil, errors.New(rsp.Message)
	}
	redislib.Redis.Set(c, "kuaidi100:"+req.Num, query, 0)
	// 数据录入数据库
	go func() {
		info, err := s.Info(c, &model.SearchFastMail{Num: req.Num, Types: req.Types})
		if err != nil {
			logrus.Error("kuaidi100查询错误:", err.Error())
		}
		if info.Id != 0 {
			rsp.Id = info.Id
		}
		rsp.Com = req.Com
		rsp.Types = req.Types
		s.Save(c, &rsp)
	}()
	return &rsp, nil
}
func (s *fastMailService) Save(c *gin.Context, req *model.ReqFastMail) error {
	if _, err := dao.Fastmail.Ctx(c).OmitEmpty().Save(req); err != nil {
		return err
	}
	return nil
}
func (s *fastMailService) Info(c *gin.Context, req *model.SearchFastMail) (*model.ReqFastMail, error) {
	where := g.Map{}
	if req.Num != "" {
		where["nu=?"] = req.Num
	}
	if req.Types != "" {
		where["types=?"] = req.Types
	}
	var m model.ReqFastMail
	err := dao.Fastmail.Ctx(c).Where(where).Scan(&m)
	return &m, err
}

func (s *fastMailService) Poll(c *gin.Context, req *model.SearchFastMail) (any, error) {
	flag := utils.FastMail().GetKd100Flags(req.Com)
	if flag == "" {
		return nil, errors.New("暂不支持此快递公司")
	}
	m := map[string]any{
		"company": flag,
		"number":  req.Num,
		"key":     utils.FastMail().Key,
		"parameters": map[string]string{
			"callbackurl": context.Global.Domain + "/mp/notify/poll",
			"phone":       req.Phone,
		},
	}
	query, err := utils.FastMail().Poll(m, "http://poll.kuaidi100.com/poll")
	if err != nil {
		return nil, err
	}
	var mp map[string]any
	gjson.Json2StructOrMap(query, &mp)
	if gconv.String(mp["result"]) == "false" {
		return nil, errors.New(gconv.String(mp["message"]))
	}
	// 订单号
	go func() {
		info, err := s.Info(c, &model.SearchFastMail{Num: req.Num, Types: req.Types})
		mail := model.ReqFastMail{
			Com:     req.Com,
			Nu:      req.Num,
			Message: "ok",
			State:   "1",
			Types:   req.Types,
		}
		if info.Id > 0 {
			mail.Id = info.Id
		}
		// 插入表中
		err = s.Save(c, &mail)
		if err != nil {
			logrus.Info("kuaidi100保存错误:", err)
		}
	}()
	return mp, nil
}

// Notify 快递100 快递信息推送
func (s *fastMailService) Notify(c *gin.Context, req *model.NotifyFastMail) error {
	redisKey := "kuaidi100:" + req.LastResult.Nu
	if req.LastResult.Nu == "" {
		return errors.New("订单号不存在")
	}
	info, err := s.Info(c, &model.SearchFastMail{Num: req.LastResult.Nu})
	if err != nil {
		return err
	}
	// 修改快递表物流状态
	data := req.LastResult
	mail := model.ReqFastMail{
		Message: data.Message,
		Nu:      data.Nu,
		Ischeck: data.Ischeck,
		Status:  data.Status,
		State:   data.State,
		Data:    gjson.StructOrMap2Json(data.Data),
	}
	if info.Id > 0 {
		mail.Id = info.Id
	}
	err = s.Save(c, &mail)
	if err != nil {
		return err
	}
	// end
	// 修改订单得物流状态
	if info.Types == "order" {
		_, err = orm.Db.Where("tracking_number=?", data.Nu).Table("order").
			Update(map[string]any{"tracking_state": data.State})
		if err != nil {
			return err
		}
	} else {
		_, err = orm.Db.Where("tracking_number=?", data.Nu).Table("coupon_order").
			Update(map[string]any{"tracking_state": data.State})
		if err != nil {
			return err
		}
	}
	// 存入redis
	redislib.Redis.Set(c, redisKey, gjson.StructOrMap2Json(data), 0)
	return nil
}
